import {
  Component,
  OnInit,
  QueryList,
  ContentChildren,
  Input,
  OnChanges,
  SimpleChanges,
} from '@angular/core';
import { BehaviorSubject, Observable, empty, from, ReplaySubject } from 'rxjs';
import {
  combineLatest,
  switchMap,
  scan,
  map,
  shareReplay,
  first,
  tap,
  startWith,
  catchError,
  filter,
  debounceTime,
} from 'rxjs/operators';
import { APIBase, ListOption, ListResult } from 'app/modules/base/api-base';
import { MySelection } from 'app/modules/base/selection';
import { DataTableColumnDirective } from '../../directives/data-table-column.directive';
import { KeySearchComponent } from '../key-search/key-search.component';

@Component({
  selector: 'm-api-data-table',
  templateUrl: './api-data-table.component.html',
  styleUrls: ['./api-data-table.component.scss'],
})
export class ApiDataTableComponent<T> implements OnInit, OnChanges {
  @ContentChildren(DataTableColumnDirective) columns: QueryList<DataTableColumnDirective>;
  @Input() dataSource: APIBase<any, T>;
  @Input() manager;
  @Input() markSelected: boolean;
  @Input() searchControl: KeySearchComponent;
  @Input() defaultOption: ListOption;
  @Input() center: boolean;

  query$ = new BehaviorSubject<ListOption>({ page: 1 });
  dataSource$ = new ReplaySubject<APIBase>();
  result$ = this.query$.pipe(
    scan((acc, obj) => ({ ...acc, ...obj })),
    combineLatest(this.dataSource$),
    debounceTime(100),
    switchMap(([opt, dataSource]) => {
      if (!dataSource) {
        return Promise.resolve(<ListResult>{
          list: [],
          total: 0,
          page: 0,
          pageSize: 0,
        });
      }
      return from(dataSource.list(opt)).pipe(
        catchError(err => {
          console.log('err', err);
          return empty();
        }),
      );
    }),
    shareReplay(1),
  );
  search$: Observable<void>;
  @Input() selection: MySelection<T>;
  selectedAll$: Observable<boolean>;
  constructor() { }

  ngOnInit() {
    this.ngOnChanges({});
  }

  ngOnChanges(changes: SimpleChanges) {
    if (changes.dataSource) {
      this.dataSource$.next(changes.dataSource.currentValue);
    }
    if (changes.defaultOption) {
      this.query$.next(this.defaultOption);
    }
    if (changes.searchControl) {
      this.search$ = this.searchControl.change.pipe(
        startWith(this.searchControl.value || null),
        filter(keyword => keyword !== null),
        tap(keyword => this.query$.next({ keyword })),
        map(() => null),
      );
    }
    if (changes.selection && changes.selection.currentValue) {
      this.selectedAll$ = this.result$.pipe(
        combineLatest(this.selection.change.pipe(startWith(null))),
        map(
          ([result]) =>
            result &&
            result.list &&
            result.list.length &&
            this.selection.isSelected(...result.list),
        ),
      );
    }
    setTimeout(() => {
      //   alert(window['HACKER'].checkThrottleFlag())
      //   if (!window['HACKER'].checkThrottleFlag()) {
      //     return false;
      //   }
      //   alert('yes')
      let obj: any = (document.querySelector('.col-md-8.col-xl-9.pl-0'))
      obj?obj.style.minHeight = '600px':null;

      // document.querySelector('.col-md-8.col-xl-9.pl-0').
    })
  }

  async refresh(abort: Promise<boolean>) {
    await abort;
    this.query$.next({});

  }

  async delete(id: number) {
    await this.dataSource.delete([id]);
    this.query$.next({});
  }

  async deleteSelected() {
    const selected = Array.from(this.selection.store.keys());
    console.log(this.selection, selected);
    await this.dataSource.delete(selected as any);
    this.selection.clear();
    this.query$.next({});
  }

  pageChange(page: number) {
    this.query$.next({ page });
  }

  search(keyword: string) {
    console.log('api table search', keyword);
    this.query$.next({ keyword });
  }

  selectAll(value: boolean = true) {
    this.result$.pipe(first()).subscribe(result => {
      if (value) {
        this.selection.select(...result.list);
      } else {
        this.selection.unselect(...result.list);
      }
    });
  }
}
